package com.spring.framework.webmvc.servlet;

import com.spring.framework.annotation.MyRequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ππ
 * @date 2020-11-17 13:48
 * @desc 声明HandlerAdapter,并通过反射调用，返回调用结果
 */

public class MyHandlerAdapter {
    public MyModelAndView handler(HttpServletRequest req, HttpServletResponse resp, MyHandlerMapping handlerMapping) throws Exception {
        //1、声明形参与位置对应关系,key为参数名，value是再参数列表中的下标
        Map<String,Integer> parameterIndexMapping = new HashMap<>();
        //对应实例
        Object instance = handlerMapping.getController();
        //调用方法
        Method method = handlerMapping.getMethod();
        //2、方法形参
        Class<?>[] parameterTypes = method.getParameterTypes();
        //3、定义实参
        Object[] parameterValues = new Object[parameterTypes.length];
        for(int i = 0; i<parameterTypes.length; i++) {
            if(parameterTypes[i] == HttpServletRequest.class || parameterTypes[i] == HttpServletResponse.class) {
                parameterIndexMapping.put(parameterTypes[i].getName(),i);
            }
        }
        Annotation[][] annotations = method.getParameterAnnotations();
        for(int i=0;i<annotations.length;i++) {
            for(Annotation a : annotations[i]) {
                if (a instanceof MyRequestParam) {
                    parameterIndexMapping.put(((MyRequestParam) a).value().trim(),i);
                }
            }
        }
        //获取传参
        Map<String,String[]> parameterMap = req.getParameterMap();
        for(Map.Entry<String,String[]> entry : parameterMap.entrySet()) {
            if(parameterIndexMapping.containsKey(entry.getKey())) {
                String value = Arrays.toString(entry.getValue())
                        .replaceAll("\\[|\\]","")
                        .replaceAll("\\s+",",");
                int index = parameterIndexMapping.get(entry.getKey());
                //赋值，允许自定义类型转化器converter，比如@ResponseBody
                parameterValues[index] =converterStringValue(value,parameterTypes[index]);
            }
        }
        if(parameterIndexMapping.containsKey(HttpServletRequest.class.getName())) {
            int index = parameterIndexMapping.get(HttpServletRequest.class.getName());
            parameterValues[index] = req;
        }
        if(parameterIndexMapping.containsKey(HttpServletResponse.class.getName())) {
            int index = parameterIndexMapping.get(HttpServletResponse.class.getName());
            parameterValues[index] = resp;
        }
        Object result = method.invoke(instance,parameterValues);
        boolean isModelAndView = method.getReturnType() == MyModelAndView.class;
        if (isModelAndView) {
            return (MyModelAndView)result;
        }
        return null;
    }

    private Object converterStringValue(String value, Class<?> parameterType) {
        if(parameterType == String.class) {
            return value;
        } else if (parameterType == Integer.class) {
            return Integer.valueOf(value);
        } else if (parameterType == Double.class) {
            return Double.valueOf(value);
        } else if (parameterType == Boolean.class) {
            return Boolean.valueOf(value);
        } else {
            return value;
        }
    }
}
